package com.agh.portal.domain.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.util.StringUtils;

public class FinderTool {
	
	public List<Object> search(List<Object> objects, List<String> properties, List<String> keywords){
		List<Score> scores = new ArrayList<Score>();
		List<Object> results = new ArrayList<Object>();
		Score dummy = new Score(0,new Object());
		scores.add(dummy);//one dummy object
		try{
			for(Object object : objects){
				//count occurences of a keyword for this object
				Integer score = 0;
				for(String property : properties){
					Object p = PropertyUtils.getProperty(object, property);
					if(p != null && p instanceof String){
						for(String k : keywords){
							score += StringUtils.countOccurrencesOf((String)p, k);
						}
					}
				}
				
				//put object score in its proper place in scores hierarchy
				if(score>0){
					Score newScore = new Score(score, object);
					for(int i=0; i<scores.size(); i++){
						
						if(scores.get(i).value <= newScore.value){
							scores.add(i, newScore);
							break;
						}
						
						if(i==scores.size()-1){
							scores.add(newScore);
							break;
						}
					}
				}
			}
			scores.remove(dummy);//remove dummy object
			
			//collect best results
			int resultCount;
			if(scores.size()<30){//show all results if less than 30
				resultCount = scores.size();
			}else{//take 20% best results and no more than 200 results overall
				resultCount = (scores.size()>1000) ? 200 : (int)(scores.size() * 0.2+1);				
			}
			
			for(int i=0; i<resultCount; i++){
				results.add(scores.get(i).object);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return results;
	}
	
	public class Score{
		public Integer value;
		public Object object;
		public Score(Integer value, Object object){
			this.value = value;
			this.object = object;
		}
	}

	
	
	public static void main(String[] args) throws InterruptedException {
		System.out.println("start");
		
		List<String> properties = new ArrayList<String>();
		properties.add("a");
		properties.add("b");
		properties.add("c");
		properties.add("d");
		properties.add("e");
		List<String> keywords = new ArrayList<String>();
		keywords.add("ALICJA");
		keywords.add("POSIADA");
		keywords.add("KOTECZKA");
		List<Object> objects = new ArrayList<Object>();
		
		Thread.sleep(1000);

		long before = 0;
		long after = 0;
		FinderTool finder = new FinderTool();
		Random r = new Random();
		int randomInt = r.nextInt(100) + 1;
		
		List<String> words = new ArrayList<String>();
		for(int i=0;i<100;i++){
			words.add("aaaaaa ");
			if(i==25){
				words.add("ALICJA ");
			}
			if(i==50){
				words.add("POSIADA ");
			}
			if(i==75){
				words.add("KOTECZKA ");
			}
		}
		
		List<Object> foundObjects = new ArrayList<Object>();
		System.out.println("====================================");
		System.out.println("Random 10+10");
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(10)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(10)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(10)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		System.out.println("====================================");
		System.out.println("Random 15+10");
		foundObjects = new ArrayList<Object>();
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(15)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(15)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(15)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		System.out.println("====================================");
		System.out.println("Random 25+10");
		foundObjects = new ArrayList<Object>();
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(25)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(25)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(25)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		System.out.println("====================================");
		System.out.println("Random 35+10");
		foundObjects = new ArrayList<Object>();
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(35)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(35)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(35)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		System.out.println("====================================");
		System.out.println("Random 55+10");
		foundObjects = new ArrayList<Object>();
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(55)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(55)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(55)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		System.out.println("====================================");
		System.out.println("Random 80+10");
		foundObjects = new ArrayList<Object>();
		objects = new ArrayList<Object>();
		for(int i =0;i<100;i++){
			for(int j=0;j<1000;j++){
				String contentA = "";
				int sentenceSize = r.nextInt(80)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentA+=words.get(r.nextInt(100));
				}
				
				String contentB = "";
				sentenceSize = r.nextInt(80)+10; 
				for(int x=0;x<sentenceSize;x++){
					contentB+=words.get(r.nextInt(100));
				}
				String contetnC = "";
				sentenceSize = r.nextInt(80)+10; 
				for(int x=0;x<sentenceSize;x++){
					contetnC+=words.get(r.nextInt(100));
				}
				objects.add(new C(contentA, contentB, contetnC));
			}
			
			foundObjects = new ArrayList<Object>();
			before = System.currentTimeMillis();
			foundObjects = finder.search(objects, properties, keywords);
			after = System.currentTimeMillis();	
			System.out.println(objects.size() +"\t" + (after - before));
		}
		
				
	}

}


